/**
 * WebSocketService
 * 
 * + startDaemons() 启动 websocket 连接并开启守护进程
 * + stopDaemons()
 * + start()  
 * + close()  
 */
const webSocketService = /** @class */ (function () {
    
    const webSocketUrl = "ws://192.168.14.252:8765/";
    var mWebsocket = null;
    var mConnected = false
    var mConnecting = false
    var mTimestamp = 0
    var mlastLogin = new Date().getTime()
    var mReconnectTimeout = 1000 * 60 * 5
    var mHeartbeats = null
    function WebSocketService() {
        this.isLogin = false
        this.daemons = null

        // this.device_id = device_id
    }
    WebSocketService.getInstance = function () {
        if (!this.instance) {
            this.instance = new WebSocketService();
        }
        return this.instance;
    };
    /**
     * 启动 webSocket 连接守护线程
     * @returns {*Thread thread
     */
    // WebSocketService.prototype.startDaemons = function (onOpen, onMessage, onClosed, onFailure) {
    WebSocketService.prototype.startDaemons = function (self, handler) {
        try {
            self.daemons = self.daemons || threads.start(function () {
                console.log("daemons started")
                while (true) {
                    self.isConnected() || self.start(self, handler)
                }
            })
            sleep(60000)
            mHeartbeats = mHeartbeats || setInterval(() => {
                mConnected = self.test(self, handler)
                if (!mConnected && new Date().getTime() - mlastLogin > 1000 * 60 * 5) {
                    // self.close(self, 1000, "Websocket 重连超时")
                    scFunc.setResultCode(ENUMS.TASK_RESULT_CODE.FAILED)
                    scFunc.setResultMsg("Websocket 尝试连接失败，超时退出")
                    exit()
                }
            }, 10000)
        } catch (error) {
            console.log("startDaemons Error", error)
        }
        return self.daemons
    };
    /**
     * 关闭 webSocket 连接守护线程
     * @returns 
     */
    WebSocketService.prototype.stopDaemons = function (self) {
        try {
            console.log("daemons stopped")
            self.daemons && self.daemons.interrupt()
            return true
        } catch (error) {
            console.log("stopDaemons Error", error)
            return false
        }
    };
    /**
     * 启动 webSocket 连接 (私有方法，不建议从外部调用)
     * @returns 
     */
    WebSocketService.prototype.start = function (self, handler) {
        try {
            self = self || this
            // if (!mConnecting && !self.test(self, handler)) {
            //     console.log("webSocket starting...")
            //     mConnecting = true
                new OkHttpClient().newWebSocket(new Request.Builder().get().url(webSocketUrl).build(), new JavaAdapter(WebSocketListener, {
                    onOpen: function (webSocket, response) {
                        mWebsocket = webSocket;
                        // mConnected = true
                        // mConnecting = false
                        // mTimestamp = new Date().getTime()
                        // typeof (handler.onOpen) == "function" && handler.onOpen(handler, self, response)
                        
                        console.log("连接成功");
                    },
                    onMessage: function (webSocket, text) {
                        // mConnecting = false
                        mlastLogin = new Date().getTime()
                        self.isLogin = true

                        typeof (handler.onMessage) == "function" && handler.onMessage(handler, self, text)
                    },
                    onClosed: function (webSocket, code, reason) {
                        mConnecting = false
                        mConnected = false
                        webSocket.close(code, reason)
                        log("webSocket 连接时长：", (new Date().getTime() - mTimestamp) + "ms")
                        typeof (handler.onClosed) == "function" && handler.onClosed(handler, self, code, reason)
                    },
                    onFailure: function (webSocket, throwable, response) {
                        mConnecting = false
                        mConnected = false
                        typeof (handler.onFailure) == "function" && handler.onFailure(handler, self, throwable, response)
                    },
                }));
                sleep(10000)
            // }
        } catch (error) {
            console.log("websocket start Error", error)
            exit()
        }
        return mWebsocket
    };
    /**
     * 
     * @returns 
     */
    WebSocketService.prototype.send = function (self, handler, msg) {
        try {
            msg = typeof (msg) != "string" ? JSON.stringify(msg) : msg
            // console.log( handler.deviceType + " send: ", msg, "\n")
            return mWebsocket && mWebsocket.send(msg)
        } catch (error) {
            console.log("websocket send Error", error)
            return false
        }
    };
    /**
     * 关闭 webSocket 连接 (私有方法，不建议从外部调用)
     * @param {number} code 
     * @param {string} msg 
     * @returns 
     */
    WebSocketService.prototype.close = function (self, code, msg) {
        try {
            console.log("webSocket 连接关闭:", mWebsocket, code, msg)
            try { clearInterval(mHeartbeats); mHeartbeats = null; } catch (error) { }
            self.stopDaemons(self)
            mWebsocket && mWebsocket.close(code, msg)
            return true
            // return !self.test(self, handler)
        } catch (error) {
            error = "websocket 关闭异常：" + JSON.stringify(error)
            console.log("webSocket 关闭异常", error)
        }
        return false
    };
    /**
     * 
     * @returns 
     */
    WebSocketService.prototype.getConnectedTime = function () {
        return mTimestamp ? new Date().getTime() - mTimestamp : 0
    };
    /**
     * 
     * @returns 
     */
    WebSocketService.prototype.getLastLoginTime = function () {
        return mlastLogin
    };
    /**
     *  (私有方法，不建议从外部调用)
     * @returns 
     */
    WebSocketService.prototype.getWebsocket = function () {
        return mWebsocket
    };
    /**
     * 
     * @returns 
     */
    WebSocketService.prototype.isConnected = function () {
        return mConnected
    };
    /**
     * 
     * @returns 
     */
    WebSocketService.prototype.test = function (self, handler) {
        try {
            let testResult = self.send(self, handler, new WebSocketMessage({
                "code": CONVERSATION_CODE.CODE_OK,
                "msg": "testing...",
                "seq": String(new Date().getTime()),
                "from": self.device_id,
                "to": self.device_id
            }).toString())

            if (testResult) {
                self.isLogin = true
                mlastLogin = new Date().getTime()
                return true
            }
        } catch (error) {
            console.log("webSocket 测试异常", error)
        }
        return false
    };
    return WebSocketService;
}()).getInstance();
webSocketService.start(webSocketService,{});
